//-------------------------------------------------
// Litchi Game Server Framework
// Copyright(c) 2019 phantaci <phantacix@qq.com>
// MIT Licensed
//-------------------------------------------------
package com.wan.util.serializer;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import java.io.IOException;
import java.util.ArrayList;

/**
 * ProtoStuff序列化与反序列
 */
public class ProtoStuffSerializer {
    /**
     * 避免每次序列化重新申请buffer空间
     */
    private static final LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);

    /* 常用和基本类型预热 */
    static {
        Class<?>[] clsArr = {Integer.class,Long.class,String.class,Short.class,Character.class,Float.class,
                    Double.class,Boolean.class};
        for (Class<?> type : clsArr) {
            getSchema(type);
        }
    }


    private static <T>Schema<T> getSchema(Class<T> clazz) {
        //自带缓存
        return RuntimeSchema.getSchema(clazz);
    }

    public static <T> byte[] encode(T obj) throws IOException {
        @SuppressWarnings("unchecked")
        Class<T> clazz = (Class<T>) obj.getClass();
        try {
            Schema<T> schema =  getSchema(clazz);
            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

    public static <T> T decode(byte[] bytes, Class<T> clazz) throws IOException {
        try {
            Schema<T> schema = getSchema(clazz);
            T message = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(bytes, message, schema);
            return message;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

}
